<template>
	<view style="background-color: #111111;">
		<view v-if="loading" class="mask" :style="{ height: scroll_h+'px'}"> </view>
		<view @touchstart="hideDrawer" class="x-scroll" :style="{ height: scroll_h+'px'}">
			<scroll-view id="scrollview" :scroll-top="scrollTop" :scroll-with-animation="true" refresher-background="#111111"
				:scroll-y="true" :scroll-anchoring="true" class="scroll-wrap" :style="{ height: scroll_h+'px'}">
				<view id="msglistview">
					<block v-for="(l,i) in list" :key="i">
						<!-- 时间轴 -->
						<view v-if="l.type===0" class="chat-time">{{l.time}}</view>
						<!-- 自定义消息 -->
						<custom v-else-if="l.type===200" :cdata="l" @customEvent="customEvent($event,i)"></custom>
						<view v-else :class="{'flex-flow':l.direction === 0}" class="chat-item">
							<view class="chat-head">
								<!-- 对象头像 -->
								<image v-if="l.direction === 1" @click="toRoute(`/pages/user/user_visitor?id=${uID(l.senderUserID)}`)"
									:src="l.userAvatarUrl" mode="aspectFill"></image>
								<!-- 自己头像 -->
								<image v-else @click="toRoute(`/pages/user/user_visitor?id=${uID(l.senderUserID)}`)"
									:src="l.userAvatarUrl" mode="aspectFill"></image>
							</view>
							<!-- 文本消息 -->
							<view v-if="l.type===1" class="chat-content">
								<text selectable="true" user-select="true">{{l.message}}</text>
							</view>
							<!-- 图片 -->
							<view v-else-if="l.type===11" class="chat-imgs"
								:style="{width: l.thumbWidth + 'px',height: l.thumbHeight + 'px'}">
								<image @click="previewImage(l.url)" :src="l.url" mode="aspectFill"> </image>
							</view>
							<!-- 音频 -->
							<view v-else-if="l.type===13" @click="playAudio(l.url,i)"
								:style="{width:`${getAudioWidth(l.duration)}rpx`}" class="chat-content chat-audio">
								<block v-if="l.direction == 0">{{l.duration}}<span>"</span>
									<view class="wifi-symbol" :class="{animation:playMsg.i==i&&playMsg.play==0}">
										<view class="wifi-circle first"></view>
										<view class="wifi-circle second"></view>
										<view class="wifi-circle third"></view>
									</view>
								</block>
								<block v-else>
									<view class="wifi-symbol direction" :class="{animation:playMsg.i==i&&playMsg.play==0}">
										<view class="wifi-circle first"></view>
										<view class="wifi-circle second"></view>
										<view class="wifi-circle third"></view>
									</view>{{l.duration}}<span>"</span>
								</block>
							</view>
						</view>
					</block>
					<view class="fit-bottom"> </view>
				</view>
			</scroll-view>
		</view>
		<view id="bottom" class="chat-body">
			<view class="chat-cell">
				<view @click="changeEvent" class="chat-switch">
					<image v-if="changeType===2" src="https://golfdate.oss-cn-shenzhen.aliyuncs.com/chat/text.png" mode="">
					</image>
					<image v-if="changeType===1" src="https://golfdate.oss-cn-shenzhen.aliyuncs.com/chat/voice.png" mode="">
					</image>
				</view>
				<view v-if="changeType===1" class="chat-input">
					<textarea auto-height="true" confirm-type="send" :confirm-hold="true" :disable-default-padding="true"
						cursor-spacing="15" :hold-keyboard="true" :show-confirm-bar="false" :adjust-position="false"
						v-model="content" @linechange="linechange" @confirm="sendEvent" @click="openDrawer"
						:focus="focus"></textarea>
				</view>
				<record v-if="changeType===2" style="flex: 1;" @record="sendRecord"></record>
				<!-- <image @click="menuEvent" class="chat-add" src="https://golfdate.oss-cn-shenzhen.aliyuncs.com/chat/add.png"
					mode=""></image> -->
				<view @click="menuEvent" class="box-add">
					<uni-icons type="plus" color="#000000" size="34"></uni-icons>
				</view>
				<view v-if="changeType===1" class="chat-send" @touchend.prevent="sendEvent"> 发送 </view>
			</view>
			<view style="transition: height 0.2s;" :style="{ height: height + 'px' }">
				<!-- 功能菜单 -->
				<view v-if="isMenu" class="chat-menu" :style="{ height: height + 'px' }">
					<view class="menu-wrap">
						<view @click="sendImage('album')" class="menu-cell">
							<view class="menu-icon">
								<uni-icons type="image" size="34" color="#1F1F1F" />
							</view>
							<text>相册</text>
						</view>
						<view @click="sendImage('camera')" class="menu-cell">
							<view class="menu-icon">
								<uni-icons type="camera-filled" size="34" color="#1F1F1F" />
							</view>
							<text>拍摄</text>
						</view>
						<view class="menu-cell" @click="groupUser">
							<view class="menu-icon">
								<uni-icons type="staff-filled" size="36"></uni-icons>
							</view>
							<text>群成员</text>
						</view>
						<view class="menu-cell" @click="nav_to(`/pages/chat/reportlist?id=${convInfo.id}&name=${convInfo.name}`)">
							<view class="menu-icon">
								<uni-icons type="info-filled" size="36"></uni-icons>
							</view>
							<text>举报</text>
						</view>
					</view>
				</view>
			</view>
			<view class="fit-bottom"> </view>
		</view>
	</view>
</template>

<script>
	import record from './record.vue';
	import custom from './custom.vue';
	import { throttle, sleep, getID } from '@/im/js/utils';
	const { safeArea, windowHeight } = uni.getSystemInfoSync()
	const cVersion = 'GRV2' //缓存版本号
	let that
	const conversationType = 2
	const delay = 400
	export default {
		components: {
			record,
			custom
		},
		data() {
			return {
				loading: true,
				title: '',
				keyboardHeight: 0,
				scroll_h: windowHeight,
				conversationID: 0,
				isFriend: true,
				list: [],
				userList: [],
				height: 0, //是否显示键盘空白栏目高度
				initBotHeight: 0, //底部初始高度
				minHeight: 0, //聊天窗口最小可视化高度
				isMenu: false, //是否显示功能菜单
				//滚动距离
				scrollTop: 0,
				changeType: 1,
				content: '',
				lineCount: 1,
				focus: false,
				//播放语音相关参数
				AUDIO: uni.createInnerAudioContext(),
				playMsg: { i: -1, play: -1 },

				gift_list: [], //礼物数组
				gift_index: -1, //当前选中礼物
				member_index: -1,
				wx_price: 200, //添加微信单次付费
			};
		},
		async onLoad(e) {
			that = this
			// setTimeout(() => { this.$refs['gift'].open() }, 2000)
			this.conversationID = e.conversationID
			if (e.conversationName) {
				this.title = e.conversationName
				uni.setNavigationBarTitle({
					title: this.title
				})
			} else {
				this.title = res.data.baseInfo.groupName
				const res = await this.$im.queryGroupInfo(this.conversationID) //优先执行获取用户头像
				uni.setNavigationBarTitle({
					title: this.title
				})
			}
			this.keyboardHeight = uni.getStorageSync(cVersion + 'keyboardHeight') || 0
			this.minHeight = uni.getStorageSync(cVersion + 'minHeight') || 0

			this.$nextTick(async () => {
				this.initBotHeight = await this.getHeight('#bottom')
				this.getList()
			})
			uni.onKeyboardHeightChange(res => {
				const keyboardHeight = res.height;
				if (keyboardHeight === 0 && this.height > 0) {
					this.changeType = 1
					this.focus = false
					this.isMenu = true
				}
				if (this.keyboardHeight) return
				clearTimeout(this._timer);
				this._timer = setTimeout(() => {
					this.keyboardHeight = keyboardHeight
					this.height = keyboardHeight
					setTimeout(async () => {
						const bottom = await this.getHeight('#bottom')
						this.minHeight = windowHeight - bottom
						this.scroll_h = this.minHeight
						this.scrollToBottom()
						uni.setStorageSync(cVersion + 'keyboardHeight', this.keyboardHeight)
						uni.setStorageSync(cVersion + 'minHeight', this.minHeight)
					}, 300)
				}, 10)
			});
			//语音自然播放结束
			this.AUDIO.onEnded(res => {
				this.playMsg = { i: -1, play: -1 };
			});
			uni.$on('receiveGroupMessage', message => {
				this.list = [...this.list, ...message]
				this.scrollToBottom(delay)
				//清除会话标记
				this.$im.clearConversationCount({ conversationID: this.conversationID, conversationType })
			})
		},
		onHide() {
			this.hideDrawer()
		},
		computed: {
			uID() {
				return (id) => {
					return getID(id)
				}
			}
		},
		onUnload() {
			uni.removeStorageSync('current_conversationID')
			uni.hideKeyboard()
			uni.offKeyboardHeightChange(() => {});
		},
		methods: {
			async getList() {
				const userList = await this.$im.queryGroupMemberList(this.conversationID) //优先执行获取用户头像
				if (userList.code === 0) {
					uni.setNavigationBarTitle({
						title: this.title + `(${userList.data.length}人)`
					})
				}
				this.list = await this.$im.queryHistoryMessage({ conversationID: this.conversationID, conversationType })
				console.log(this.list);
				this.scroll_h = windowHeight - this.initBotHeight
				this.scrollToBottom(delay)
			},
			sendEvent: throttle(() => {
				if (that.content === '') return
				const message = that.content
				that.content = ''
				that.$im.sendMessage({ conversationID: that.conversationID, message, conversationType }, (data) => {
					that.list = [...that.list, ...that.$im.messageAttribute(data)]
					that.scrollToBottom(50)
				})
			}),
			//发送语音
			async sendRecord({ filePath, duration }) {
				const res = await this.$im.sendAudioMessage({
					conversationID: this.conversationID,
					filePath,
					duration,
					conversationType
				})
				if (res.code === 0) {
					this.list = [...this.list, ...res.data]
					this.scrollToBottom(50)
					return
				}
				uni.showToast({
					title: '发送失败',
					icon: 'none'
				})
			},
			//播放语音
			playAudio(url, i) {
				if (this.playMsg.i == i) {
					if (this.playMsg.play == 0) {
						this.playMsg = { i, play: 1 };
						return this.AUDIO.pause();
					} else {
						this.playMsg = { i, play: 0 };
						return this.AUDIO.play();
					}
				}
				this.playMsg = { i, play: 0 };
				this.AUDIO.src = url;
				this.$nextTick(function() {
					this.AUDIO.play();
				});
			},
			async sendImage(sourceType) {
				const res = await this.$im.sendImageMessage({
					conversationID: this.conversationID,
					sourceType,
					conversationType
				})
				if (res.code === 0) {
					this.list = [...this.list, ...res.data]
					this.scrollToBottom(50)
					return
				}
				uni.showToast({
					title: '发送失败',
					icon: 'none'
				})
			},
			groupUser() {
				uni.navigateTo({
					url: `/pages/chat/group_member?id=${this.conversationID}`
				})
			},
			async customEvent(e, i) {
				const d = e.data
			},
			changeEvent() {
				this.isMenu = false
				this.changeType = this.changeType === 1 ? 2 : 1
				if (this.changeType === 2) {
					this.hideDrawer();
					return
				}
				this.openDrawer()
			},
			menuEvent() {
				this.isMenu = this.isMenu ? false : true
				if (this.isMenu) {
					this.changeType = 1
					this.focus = false
					uni.hideKeyboard()
					if (!this.keyboardHeight) return this.focus = true //暂时这么处理

					this.height = this.keyboardHeight
					this.scroll_h = this.minHeight
					this.scrollToBottom()
					return
				}
				this.focus = true
				this.height = this.keyboardHeight
				this.scroll_h = this.minHeight
			},
			openDrawer() {
				this.isMenu = false
				if (this.keyboardHeight) {
					this.focus = true
					this.height = this.keyboardHeight
					this.scroll_h = this.minHeight
					this.scrollToBottom()
				}
			},
			hideDrawer() {
				if (this.height === 0) return
				this.focus = false
				this.height = 0
				this.isMenu = false
				this.scroll_h = windowHeight - this.initBotHeight
				this.scrollToBottom()
				uni.hideKeyboard()
			},
			async linechange(e) {
				const { lineCount } = e.detail
				if (this.lineCount === lineCount) return
				this.lineCount = lineCount
				const height = await this.getHeight('#bottom')
				this.scroll_h = windowHeight - height
				this.scrollToBottom()
			},
			// 滚动至聊天底部
			async scrollToBottom(wait) {
				// this.scrollTop = this.scrollTop > 0 ? this.scrollTop + 0.01 : ''
				if (wait) await sleep(wait)
				let query = uni.createSelectorQuery().in(this);
				query.select('#msglistview').boundingClientRect();
				query.exec(async (res) => {
					if (res[0].height > this.scroll_h) {
						this.scrollTop = res[0].height - this.scroll_h + 50
					}
					if (this.loading) {
						await sleep(400)
						this.loading = false
					}
				})
			},
			getHeight(id) {
				return new Promise(resolve => {
					let query = uni.createSelectorQuery().in(this);
					query.select(id).boundingClientRect();
					query.exec((res) => {
						resolve(res[0].height)
					})
				})
			},
			getAudioWidth(length) {
				const len = length >= 50 ? 14 : length >= 40 ? 13 : length >= 30 ? 12 : length >= 20 ? 11 : length >= 10 ?
					10 : length
				return 140 + 15 * len
			},
			previewImage(url) {
				uni.previewImage({
					current: 0,
					urls: [url],
				});
			},
			copyText(str) {
				uni.setClipboardData({
					data: str,
					success() {}
				});
			},
			toRoute(url) {
				uni.navigateTo({
					url
				})
			}
		}
	};
</script>

<style lang="scss" scoped>
	@import "assets/chat.scss";
</style>